﻿/*
* Copyright (C) 2020 ~ 2024 chaigec All Rights Reserved.
*
* Author:     chaigec <chaigec@163.com>
* Maintainer: chaigec <chaigec@163.com>

 * Use of this source code is governed by MIT license that can be found in the
 * LICENSE file in the root of the source tree. All contributing project authors
 * may be found in the AUTHORS file in the root of the source tree.
*/

#include "MkGbPtz.h"
#include "MkUtil/MkUtil.h"
#include "MkUtil/MkLog.h"
#include <string.h>

CGbPtzCommand::CGbPtzCommand()
{

}

CGbPtzCommand::~CGbPtzCommand()
{

}

Uint32 CGbPtzCommand::ToGbString(OUT MkString &OutString)
{
    Uint16 Address = 0x01;
    Uint8 PtzByteCmd[8] = { 0 };
    //first Byte A5
    PtzByteCmd[0] = 0xA5;
    //high 4bit version 1.0=0  low 4bit check bits = (0 Byte high 4bit +  0 Byte low 4bit + 1 Byte high 4bit) % 16
    PtzByteCmd[1] = (0 << 4) + (((PtzByteCmd[0] >> 4) + (PtzByteCmd[0] & 0xf) + 0) & 0xf);
    //address low 8bit
    PtzByteCmd[2] = Address & 0xff;
    //code
    PtzByteCmd[3] = m_CmdType;
    PtzByteCmd[4] = m_Param1;
    PtzByteCmd[5] = m_Param2;
    PtzByteCmd[6] = (m_Param3 << 4) | (Address >> 12);

    //check byte = (form 0 to 6 byte)%256
    PtzByteCmd[7] = (PtzByteCmd[0] + PtzByteCmd[1] + PtzByteCmd[2] + PtzByteCmd[3] + PtzByteCmd[4] + PtzByteCmd[5] + PtzByteCmd[6]) & 0xff;
    CMkUtil::ByteToString(PtzByteCmd, 8, OutString);
    return NoneError;
}

CGbPtzCommand *CGbPtzCommand::FromString(const MkString &GbCmd)
{
    CGbPtzCommand *pPtz = new CGbPtzCommand;
    if (!pPtz) {
        MkErrorLog("new buffer failed\n");
        return nullptr;
    }
    Uint8 PtzByteCmd[Len16] = { 0 };
    Uint32 nLen = 0;
    CMkUtil::StringToByte(GbCmd, PtzByteCmd, nLen);

    //check 1Byte 
    if (PtzByteCmd[1] != ((0 << 4) + (((PtzByteCmd[0] >> 4) + (PtzByteCmd[0] & 0xf) + 0) & 0xf))
        || PtzByteCmd[7] != ((PtzByteCmd[0] + PtzByteCmd[1] + PtzByteCmd[2] + PtzByteCmd[3] + PtzByteCmd[4] + PtzByteCmd[5] + PtzByteCmd[6]) & 0xff)) {
        MkDelete(pPtz);
        return nullptr;
    }
    pPtz->m_CmdType = (MkGbPtzCommandType)PtzByteCmd[3];
    pPtz->m_Param1 = PtzByteCmd[4];
    pPtz->m_Param2 = PtzByteCmd[5];
    pPtz->m_Param3 = PtzByteCmd[6] >> 4;
    return pPtz;
}

CGbPtzCommand *CGbPtzCommand::CreateNew(const MkGbPtzCommandType &CmdType, Uint8 Param1, Uint8 Param2, Uint8 Param3)
{
    CGbPtzCommand *pPtz = new CGbPtzCommand;
    if (!pPtz) {
        MkErrorLog("new ptz failed\n");
        return nullptr;
    }

    pPtz->m_CmdType = CmdType;
    pPtz->m_Param1 = Param1;
    pPtz->m_Param2 = Param2;
    pPtz->m_Param3 = Param3;
    return pPtz;
}


